﻿using System;
using System.IO;
using System.Net;
using System.Web;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public static class JsonTestObjects
{
    public static string JWSHead = "{\"typ\":\"JWT\",\r\n \"alg\":\"RS256\"}";
    public static string PIECE_OF_CAKE_ORDERID = "3485709183457474939449";
    public static string PIECE_OF_CAKE = "{" +
          "\"iss\": \"Google\"," +
          "\"aud\": \"1337133713371337\"," +
          "\"typ\": \"google/payments/inapp/item/v1/postback/buy\"," +
          "\"iat\": \"1309988959\"," +
          "\"exp\": \"1409988959\"," +
          "\"request\": {" +
            "\"name\": \"Piece of Cake\"," +
            "\"description\": \"Virtual chocolate cake to fill your virtual tummy\"," +
            "\"price\": \"10.50\"," +
            "\"currencyCode\": \"USD\"," +
            "\"sellerData\": \"user_id:1224245,offer_code:3098576987,affiliate:aksdfbovu9j\"" +
          "}," +
          "\"response\": {" +
            "\"orderId\": \"3485709183457474939449\"" +
          "}" +
        "}";

}

[TestFixture]
public class testPostBack
{

    [Test]
    public void jwtJSONToObject()
    {

        JObject jobj = JObject.Parse(JsonTestObjects.PIECE_OF_CAKE);
        Console.WriteLine("iss: {0}", (string)jobj["iss"]);
        Console.WriteLine("aud: {0}", (string)jobj["aud"]);
        Console.WriteLine("typ: {0}", (string)jobj["typ"]);
        Console.WriteLine("iat: {0}", (string)jobj["iat"]);
        Console.WriteLine("exp: {0}", (string)jobj["exp"]);
        Console.WriteLine("request.name: {0}", (string)jobj["request"]["name"]);
        Console.WriteLine("request.description: {0}", (string)jobj["request"]["description"]);
        Console.WriteLine("request.price: {0}", (string)jobj["request"]["price"]);
        Console.WriteLine("request.currencyCode: {0}", (string)jobj["request"]["currencyCode"]);
        Console.WriteLine("request.sellerData: {0}", (string)jobj["request"]["sellerData"]);
        Console.WriteLine("response.orderId:  {0}", (string)jobj["response"]["orderId"]);

    }
    string _postAddress = null;
    [TestCase(@"http://local.kstubs.com/demo/googlepurchase/GoogleWalletProcessing.aspx")]
    [TestCase(@"http://meetscoresonline.com/GoogleWalletProcessing.aspx")]
    public void succesfullPost(string PostAddress)
    {

        _postAddress = PostAddress;

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_postAddress);
        request.Method = "POST";
        request.ContentType = "text/json";

        Stub.Jwt.JsonWebToken jwt = new Stub.Jwt.JsonWebToken();
        var j = String.Format("jwt={0}", jwt.Generate(JsonTestObjects.JWSHead, JsonTestObjects.PIECE_OF_CAKE, "RxMr0dZSP9WAfKC5vJ_n3w"));
        byte[] bytes = System.Text.UTF8Encoding.UTF8.GetBytes(j);
        request.ContentLength = bytes.Length;

        Stream s = request.GetRequestStream();
        s.Write(bytes, 0, bytes.Length);
        s.Flush();

        FileStream f = null;
        Stream w = null;

        try
        {
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            StringBuilder sb = new StringBuilder();

            if (response.StatusCode == HttpStatusCode.OK)
            {
                Utility.WriteStreamToSB(response.GetResponseStream(), sb);
                Assert.AreEqual(JsonTestObjects.PIECE_OF_CAKE_ORDERID, sb.ToString());
            }
            else
                throw new Exception("Invalid Web Service Response");
        }
        finally
        {
            if (f != null)
                f.Close();
            if (w != null)
                w.Close();
        }

    }
    
    [TestCase(@"http://local.kstubs.com/demo/googlepurchase/GoogleWalletProcessing.aspx")]
    public void test(string PostAddress)
    {
        _postAddress = PostAddress;
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_postAddress);

        var body = Encoding.UTF8.GetBytes(JsonTestObjects.PIECE_OF_CAKE);

        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.Timeout = 10000;
        request.ContentLength = body.Length;

        Stream s = request.GetRequestStream();
        s.Write(body, 0, body.Length);

        s.Flush();
        s.Close();

        FileStream f = null;
        Stream w = null;

        try
        {
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            StringBuilder sb = new StringBuilder();

            if (response.StatusCode == HttpStatusCode.OK)
            {
                Utility.WriteStreamToSB(response.GetResponseStream(), sb);
                Assert.AreEqual(JsonTestObjects.PIECE_OF_CAKE_ORDERID, sb.ToString());
            }
            else
                throw new Exception("Invalid Web Service Response");
        }
        finally
        {
            if (f != null)
                f.Close();
            if (w != null)
                w.Close();
        }

    }
}

public static class Utility
{
    public static void WriteStreamToSB(Stream readStream, StringBuilder SB)
    {
        readStream.Flush();

        if (readStream.CanSeek)
            readStream.Seek(0, SeekOrigin.Begin);

        using (StringWriter writer = new StringWriter(SB))
        {

            int Length = 256;
            Byte[] buffer = new Byte[Length];
            int bytesRead = readStream.Read(buffer, 0, Length);
            // write the required bytes
            while (bytesRead > 0)
            {
                writer.Write(Encoding.UTF8.GetString(buffer).Trim(new char[] { '\0' }));
                bytesRead = readStream.Read(buffer, 0, Length);
            }

            writer.Flush();
        }
    }
}

